//! jwt 预定义的标准化声明
//!   - iss(Issuer) 签发者
//!   - sub(Subject) 主题（用户ID或其他唯一标识）
//!   - aud(Audience) 目标受众（接收方）
//!   - exp(Expiration) 过期时间（Unix时间戳，必选）
//!   - nbf(Not Before) 生效时间（在此之前Token无效）
//!   - iat(Issued At) 签发时间（用于计算Token年龄）
//!   - jti(JWT ID) Token唯一标识（防重放攻击）
//!
use std::thread;
use std::time::Duration;
use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;

#[derive(Debug, Serialize, Deserialize)]
struct Claims {
    sub: String,
    company: String,
    // 必须要有的字段
    exp: i64,
}


/// jwt编码
fn jwt_encode<T: Serialize>(t: &T) -> String {

    let header = Header { alg: Algorithm::HS512, ..Default::default() };
    let token = encode(
        &header,
        t,
        &EncodingKey::from_secret("secret".as_ref())
    ).unwrap();
    println!("token: {}", token);
    token
}

/// jwt解码
/// T: DeserializeOwned 表示T要实现Deserialize trait
fn jwt_decode<T: DeserializeOwned>(token: String) -> T {
    // Claims is a struct that implements Deserialize
    let token_message = decode::<T>(
        &token,
        &DecodingKey::from_secret("secret".as_ref()),
        &Validation::new(Algorithm::HS512)
    ).unwrap();
    //println!("{:?}", token_message.unwrap().claims);
    token_message.claims
}
fn main() {
    let exp = OffsetDateTime::now_utc().unix_timestamp();
    let my_claims = Claims {
        sub: "b@b.com".to_owned(),
        company: "ACME".to_owned(),
        exp,
    };
    thread::sleep(Duration::from_secs(1));
    let decode: Claims = jwt_decode(jwt_encode(&my_claims));
    let exp = OffsetDateTime::now_utc().unix_timestamp();
    println!("{:?}", decode);
    
    if exp > decode.exp{
        println!("token expired");
    }
}